package com.yunchao.app.presentation.configure

import androidx.lifecycle.viewModelScope
import com.yunchao.feature.base.HTTP_DOMAIN_INPUT_URL
import com.yunchao.feature.base.data.CacheManager
import com.yunchao.feature.base.domain.constants.DEVICE_NUMBER_KEY
import com.yunchao.feature.base.domain.constants.LOOP_POWER_KEY
import com.yunchao.feature.base.domain.constants.SERVER_IP_KEY
import com.yunchao.feature.base.domain.constants.SERVER_PORT_KEY
import com.yunchao.feature.base.domain.constants.SINGLE_POWER_KEY
import com.yunchao.feature.base.presentation.viewmodel.BaseAction
import com.yunchao.feature.base.presentation.viewmodel.BaseEffect
import com.yunchao.feature.base.presentation.viewmodel.BaseState
import com.yunchao.feature.base.presentation.viewmodel.BaseViewModel
import kotlinx.coroutines.launch
import me.jessyan.retrofiturlmanager.RetrofitUrlManager

internal class ConfigureViewModel :
    BaseViewModel<ConfigureViewModel.UiState, ConfigureViewModel.Action, ConfigureViewModel.UiEffect>(
        UiState.Idle
    ) {
    init {
        loadConfigure()
    }

    fun loadConfigure() = viewModelScope.launch {
        val serverIp = CacheManager.getString(SERVER_IP_KEY)
        val serverPort = CacheManager.getString(SERVER_PORT_KEY)
        val number = CacheManager.getString(DEVICE_NUMBER_KEY)
        val singlePower = CacheManager.getString(SINGLE_POWER_KEY)
        val loopPower = CacheManager.getString(LOOP_POWER_KEY)
        sendAction(
            Action.LoadConfigureSuccess(
                serverIp.orEmpty(),
                serverPort ?: "18300",
                number.orEmpty(),
                singlePower ?: "10",
                loopPower ?: "30"
            )
        )
    }

    fun saveConfigure(
        isShowBack: Boolean,
        serverIp: String,
        serverPort: String,
        number: String,
        singlePower: String,
        loopPower: String
    ) = viewModelScope.launch {
        postSideEffect(UiEffect.ShowLoading)
        runCatching {
            CacheManager.putString(SERVER_IP_KEY, serverIp)
            CacheManager.putString(SERVER_PORT_KEY, serverPort)
            CacheManager.putString(DEVICE_NUMBER_KEY, number)
            CacheManager.putString(SINGLE_POWER_KEY, singlePower)
            CacheManager.putString(LOOP_POWER_KEY, loopPower)
        }.onFailure {
            postSideEffect(UiEffect.ShowToast("保存失败")).apply {
                postSideEffect(UiEffect.HideLoading)
            }
        }.onSuccess {
            RetrofitUrlManager.getInstance().putDomain(HTTP_DOMAIN_INPUT_URL, "http://$serverIp:$serverPort")
                .apply {
                    postSideEffect(UiEffect.HideLoading)
                }.apply {
                    if (isShowBack) {
                        postSideEffect(UiEffect.CloseSelf)
                    } else {
                        postSideEffect(UiEffect.NavigateToMain)
                    }
                }
        }
    }


    internal sealed interface Action : BaseAction<UiState> {

        data class LoadConfigureSuccess(
            val serverIp: String,
            val serverPort: String,
            val number: String,
            val singlePower: String,
            val loopPower: String
        ) : Action {
            override fun reduce(state: UiState) =
                UiState.Success(serverIp, serverPort, number, singlePower, loopPower)
        }
    }

    internal sealed interface UiState : BaseState {
        data class Success(
            val serverIp: String,
            val serverPort: String,
            val number: String,
            val singlePower: String,
            val loopPower: String
        ) : UiState

        data object Idle : UiState
    }

    internal sealed interface UiEffect : BaseEffect {
        data object ShowLoading : UiEffect
        data object HideLoading : UiEffect
        data class ShowToast(val msg: String) : UiEffect
        data object NavigateToMain : UiEffect
        data object CloseSelf : UiEffect
    }
}